package com.shuda.business.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuda.business.crm.dto.CustomerDTO;
import com.shuda.business.crm.dto.CustomerQueryDTO;
import com.shuda.business.crm.entity.CustomerEntity;
import com.shuda.business.crm.entity.CustomerStatusHistoryEntity;
import com.shuda.business.crm.mapper.CustomerMapper;
import com.shuda.business.crm.service.CustomerService;
import com.shuda.business.crm.service.CustomerStatusHistoryService;
import com.shuda.common.core.domain.PageDTO;
import com.shuda.common.core.domain.PageResult;
import com.shuda.common.core.exception.BusinessException;
import com.shuda.common.security.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * CRM客户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, CustomerEntity> 
        implements CustomerService {

    private static final Logger logger = LoggerFactory.getLogger(CustomerServiceImpl.class);

    private final CustomerMapper customerMapper;
    private final CustomerStatusHistoryService customerStatusHistoryService;

    @Override
    public PageResult<CustomerDTO> getCustomerPage(PageDTO pageDTO, CustomerQueryDTO queryDTO) {
        LambdaQueryWrapper<CustomerEntity> wrapper = new LambdaQueryWrapper<>();
        
        if (queryDTO.getCustomerName() != null) {
            wrapper.like(CustomerEntity::getCustomerName, queryDTO.getCustomerName());
        }
        
        if (queryDTO.getCustomerPhone() != null) {
            wrapper.like(CustomerEntity::getCustomerPhone, queryDTO.getCustomerPhone());
        }
        
        if (queryDTO.getCustomerStatus() != null) {
            wrapper.eq(CustomerEntity::getCustomerStatus, queryDTO.getCustomerStatus());
        }
        
        if (queryDTO.getCustomerLevel() != null) {
            wrapper.eq(CustomerEntity::getCustomerLevel, queryDTO.getCustomerLevel());
        }
        
        if (queryDTO.getAssignedUserId() != null) {
            wrapper.eq(CustomerEntity::getAssignedUserId, queryDTO.getAssignedUserId());
        }
        
        if (queryDTO.getStartTime() != null && queryDTO.getEndTime() != null) {
            wrapper.between(CustomerEntity::getCreateTime, queryDTO.getStartTime(), queryDTO.getEndTime());
        }
        
        wrapper.orderByDesc(CustomerEntity::getCreateTime);
        
        IPage<CustomerEntity> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        IPage<CustomerEntity> resultPage = this.page(page, wrapper);
        
        List<CustomerDTO> dtoList = resultPage.getRecords().stream().map(entity -> {
            CustomerDTO dto = new CustomerDTO();
            dto.setId(entity.getId());
            dto.setCustomerName(entity.getCustomerName());
            dto.setCustomerPhone(entity.getCustomerPhone());
            dto.setCustomerEmail(entity.getCustomerEmail());
            dto.setCustomerStatus(entity.getCustomerStatus());
            dto.setCustomerLevel(entity.getCustomerLevel());
            dto.setCustomerSource(entity.getCustomerSource());
            dto.setCustomerIndustry(entity.getCustomerIndustry());
            dto.setCustomerCompany(entity.getCustomerCompany());
            dto.setCustomerPosition(entity.getCustomerPosition());
            dto.setCustomerAddress(entity.getCustomerAddress());
            dto.setCustomerRemark(entity.getCustomerRemark());
            dto.setAssignedUserId(entity.getAssignedUserId());
            dto.setAssignedUserName(entity.getAssignedUserName());
            dto.setLastFollowUpTime(entity.getLastFollowUpTime());
            dto.setNextFollowUpTime(entity.getNextFollowUpTime());
            dto.setCreateTime(entity.getCreateTime());
            dto.setUpdateTime(entity.getUpdateTime());
            return dto;
        }).collect(Collectors.toList());
        
        return new PageResult<>(dtoList, resultPage.getTotal(), resultPage.getCurrent(), resultPage.getSize());
    }

    @Override
    public CustomerDTO getCustomerById(Long id) {
        CustomerEntity entity = this.getById(id);
        if (entity == null) {
            throw new BusinessException("客户不存在");
        }
        
        CustomerDTO dto = new CustomerDTO();
        dto.setId(entity.getId());
        dto.setCustomerName(entity.getCustomerName());
        dto.setCustomerPhone(entity.getCustomerPhone());
        dto.setCustomerEmail(entity.getCustomerEmail());
        dto.setCustomerStatus(entity.getCustomerStatus());
        dto.setCustomerLevel(entity.getCustomerLevel());
        dto.setCustomerSource(entity.getCustomerSource());
        dto.setCustomerIndustry(entity.getCustomerIndustry());
        dto.setCustomerCompany(entity.getCustomerCompany());
        dto.setCustomerPosition(entity.getCustomerPosition());
        dto.setCustomerAddress(entity.getCustomerAddress());
        dto.setCustomerRemark(entity.getCustomerRemark());
        dto.setAssignedUserId(entity.getAssignedUserId());
        dto.setAssignedUserName(entity.getAssignedUserName());
        dto.setLastFollowUpTime(entity.getLastFollowUpTime());
        dto.setNextFollowUpTime(entity.getNextFollowUpTime());
        dto.setCreateTime(entity.getCreateTime());
        dto.setUpdateTime(entity.getUpdateTime());
        
        return dto;
    }

    @Override
    @Transactional
    public CustomerDTO createCustomer(CustomerDTO customerDTO) {
        // 检查手机号是否已存在
        LambdaQueryWrapper<CustomerEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerEntity::getCustomerPhone, customerDTO.getCustomerPhone())
               .eq(CustomerEntity::getDeleted, 0);
        
        if (this.count(wrapper) > 0) {
            throw new BusinessException("客户手机号已存在");
        }
        
        CustomerEntity entity = new CustomerEntity();
        entity.setCustomerName(customerDTO.getCustomerName());
        entity.setCustomerPhone(customerDTO.getCustomerPhone());
        entity.setCustomerEmail(customerDTO.getCustomerEmail());
        entity.setCustomerStatus(customerDTO.getCustomerStatus());
        entity.setCustomerLevel(customerDTO.getCustomerLevel());
        entity.setCustomerSource(customerDTO.getCustomerSource());
        entity.setCustomerIndustry(customerDTO.getCustomerIndustry());
        entity.setCustomerCompany(customerDTO.getCustomerCompany());
        entity.setCustomerPosition(customerDTO.getCustomerPosition());
        entity.setCustomerAddress(customerDTO.getCustomerAddress());
        entity.setCustomerRemark(customerDTO.getCustomerRemark());
        entity.setCreateBy(SecurityUtils.getCurrentUsername());
        
        this.save(entity);
        
        customerDTO.setId(entity.getId());
        customerDTO.setCreateTime(entity.getCreateTime());
        customerDTO.setUpdateTime(entity.getUpdateTime());
        
        return customerDTO;
    }

    @Override
    @Transactional
    public CustomerDTO updateCustomer(Long id, CustomerDTO customerDTO) {
        CustomerEntity entity = this.getById(id);
        if (entity == null) {
            throw new BusinessException("客户不存在");
        }
        
        // 如果手机号发生变化，检查新手机号是否已存在
        if (!entity.getCustomerPhone().equals(customerDTO.getCustomerPhone())) {
            LambdaQueryWrapper<CustomerEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CustomerEntity::getCustomerPhone, customerDTO.getCustomerPhone())
                   .ne(CustomerEntity::getId, id)
                   .eq(CustomerEntity::getDeleted, 0);
            
            if (this.count(wrapper) > 0) {
                throw new BusinessException("客户手机号已存在");
            }
        }
        
        entity.setCustomerName(customerDTO.getCustomerName());
        entity.setCustomerPhone(customerDTO.getCustomerPhone());
        entity.setCustomerEmail(customerDTO.getCustomerEmail());
        entity.setCustomerStatus(customerDTO.getCustomerStatus());
        entity.setCustomerLevel(customerDTO.getCustomerLevel());
        entity.setCustomerSource(customerDTO.getCustomerSource());
        entity.setCustomerIndustry(customerDTO.getCustomerIndustry());
        entity.setCustomerCompany(customerDTO.getCustomerCompany());
        entity.setCustomerPosition(customerDTO.getCustomerPosition());
        entity.setCustomerAddress(customerDTO.getCustomerAddress());
        entity.setCustomerRemark(customerDTO.getCustomerRemark());
        entity.setUpdateBy(SecurityUtils.getCurrentUsername());
        
        this.updateById(entity);
        
        customerDTO.setId(entity.getId());
        customerDTO.setUpdateTime(entity.getUpdateTime());
        
        return customerDTO;
    }

    @Override
    @Transactional
    public Boolean deleteCustomer(Long id) {
        CustomerEntity entity = this.getById(id);
        if (entity == null) {
            throw new BusinessException("客户不存在");
        }
        
        entity.setUpdateBy(SecurityUtils.getCurrentUsername());
        this.updateById(entity);
        
        return this.removeById(id);
    }

    @Override
    @Transactional
    public Boolean batchDeleteCustomers(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }
        
        String currentUsername = SecurityUtils.getCurrentUsername();
        LocalDateTime now = LocalDateTime.now();
        
        List<CustomerEntity> entities = ids.stream().map(id -> {
            CustomerEntity entity = new CustomerEntity();
            entity.setId(id);
            entity.setUpdateBy(currentUsername);
            entity.setUpdateTime(now);
            return entity;
        }).collect(Collectors.toList());
        
        this.updateBatchById(entities);
        
        return this.removeByIds(ids);
    }

    @Override
    @Transactional
    public Boolean updateCustomerStatus(Long id, String status) {
        CustomerEntity entity = this.getById(id);
        if (entity == null) {
            throw new BusinessException("客户不存在");
        }
        
        // 记录状态变更历史
        String oldStatus = entity.getCustomerStatus();
        String newStatus = status;
        
        // 只有在状态确实发生变化时才记录历史
        if (!oldStatus.equals(newStatus)) {
            CustomerStatusHistoryEntity historyEntity = new CustomerStatusHistoryEntity();
            historyEntity.setCustomerId(id);
            historyEntity.setCustomerName(entity.getCustomerName());
            historyEntity.setOldStatus(oldStatus);
            historyEntity.setNewStatus(newStatus);
            historyEntity.setChangeReason("手动状态更新");
            historyEntity.setOperatorId(SecurityUtils.getCurrentUserId());
            historyEntity.setOperatorName(SecurityUtils.getCurrentUsername());
            historyEntity.setOperatorTime(LocalDateTime.now());
            
            customerStatusHistoryService.createCustomerStatusHistory(historyEntity);
        }
        
        entity.setCustomerStatus(status);
        entity.setUpdateBy(SecurityUtils.getCurrentUsername());
        
        return this.updateById(entity);
    }

    @Override
    @Transactional
    public Boolean assignCustomer(Long id, Long userId) {
        CustomerEntity entity = this.getById(id);
        if (entity == null) {
            throw new BusinessException("客户不存在");
        }
        
        entity.setAssignedUserId(userId);
        entity.setAssignedUserName(getUserNameById(userId));
        entity.setUpdateBy(SecurityUtils.getCurrentUsername());
        
        return this.updateById(entity);
    }

    @Override
    @Transactional
    public Boolean batchAssignCustomers(List<Long> customerIds, Long userId) {
        if (customerIds == null || customerIds.isEmpty()) {
            return true;
        }
        
        String currentUsername = SecurityUtils.getCurrentUsername();
        String userName = getUserNameById(userId);
        LocalDateTime now = LocalDateTime.now();
        
        List<CustomerEntity> entities = customerIds.stream().map(id -> {
            CustomerEntity entity = new CustomerEntity();
            entity.setId(id);
            entity.setAssignedUserId(userId);
            entity.setAssignedUserName(userName);
            entity.setUpdateBy(currentUsername);
            entity.setUpdateTime(now);
            return entity;
        }).collect(Collectors.toList());
        
        return this.updateBatchById(entities);
    }

    @Override
    public List<Object> getCustomerFollowUps(Long id) {
        // 这里应该实现获取客户跟进记录的逻辑
        // 暂时返回空列表
        return new ArrayList<>();
    }

    @Override
    @Transactional
    public Boolean addCustomerFollowUp(Long id, Object followUpDTO) {
        // 这里应该实现添加客户跟进记录的逻辑
        // 暂时返回true
        logger.info("添加客户跟进记录，客户ID：{}，跟进信息：{}", id, followUpDTO);
        return true;
    }

    @Override
    public Object getCustomerStatistics() {
        // 获取客户统计信息
        Map<String, Object> statistics = new HashMap<>();
        
        // 总客户数
        LambdaQueryWrapper<CustomerEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CustomerEntity::getDeleted, 0);
        statistics.put("totalCustomers", this.count(wrapper));
        
        // 按状态统计
        Map<String, Long> statusCount = new HashMap<>();
        statusCount.put("active", this.count(wrapper.clone().eq(CustomerEntity::getCustomerStatus, "active")));
        statusCount.put("inactive", this.count(wrapper.clone().eq(CustomerEntity::getCustomerStatus, "inactive")));
        statusCount.put("potential", this.count(wrapper.clone().eq(CustomerEntity::getCustomerStatus, "potential")));
        statistics.put("statusCount", statusCount);
        
        // 按级别统计
        Map<String, Long> levelCount = new HashMap<>();
        levelCount.put("A", this.count(wrapper.clone().eq(CustomerEntity::getCustomerLevel, "A")));
        levelCount.put("B", this.count(wrapper.clone().eq(CustomerEntity::getCustomerLevel, "B")));
        levelCount.put("C", this.count(wrapper.clone().eq(CustomerEntity::getCustomerLevel, "C")));
        statistics.put("levelCount", levelCount);
        
        return statistics;
    }

    @Override
    public byte[] exportCustomerData(CustomerQueryDTO queryDTO) {
        // 这里应该实现客户数据导出功能
        // 暂时返回空字节数组
        logger.info("导出客户数据，查询条件：{}", queryDTO);
        return new byte[0];
    }
    
    /**
     * 根据用户ID获取用户名
     */
    private String getUserNameById(Long userId) {
        // 这里应该实现根据用户ID获取用户名的逻辑
        // 暂时返回模拟的用户名
        return "用户" + userId;
    }
}